package com.lemon.components.video;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.LinkedList;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.lemon.components.common.result.ResultBase;
import com.lemon.components.video.bean.VideoCoverOrder;
import com.lemon.components.video.bean.VideoInfoOrder;
import com.lemon.components.video.info.VideoInfo;
import com.lemon.components.video.result.VideoInfoResult;

public class VideoUtils {
	
	public static VideoInfoResult videoInfo(VideoInfoOrder videoInfoOrder){
		VideoInfoResult result = new VideoInfoResult();
		try {
			videoInfoOrder.check();
		} catch (Exception e) {
			result.setMessage(e.getMessage());
			return result;
		}
		File videoFile = new File(videoInfoOrder.getVideoPath());
		if(!videoFile.exists()){
			result.setMessage("视频文件["+videoInfoOrder.getVideoPath()+"]不存在！");
			return result;
		}
		
		String videoInfoCmd = "cmd /c ffprobe -v quiet -print_format json -show_format -show_streams "+videoInfoOrder.getVideoPath();
		
		try {
			Process p = Runtime.getRuntime().exec(videoInfoCmd, null, new File(videoInfoOrder.getFfmpeglib()));
			Thread inputTread = new Thread(new Runnable() {
			    @Override
				public void run() {
			    	try {
				    	BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(),"utf-8"));
				    	String tmp;
				    	StringBuilder sb = new StringBuilder();
			    		while((tmp = br.readLine())!=null){
			    			sb.append(tmp);
			    		}
			    		VideoInfo videoInfo = JSONObject.parseObject(sb.toString(), VideoInfo.class);
			    		result.setVideoInfo(videoInfo);
			    		result.setSuccess(true);
					} catch (Exception e) {
						e.printStackTrace();
					}
			    }
			});
			inputTread.start();
			inputTread.join();
			new Thread(new Runnable() {
			    @Override
				public void run() {
			    	try {
				    	BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream(),"utf-8"));
				    	String tmp;
			    		while((tmp = br.readLine())!=null){
			    			System.err.println(tmp);
			    		}
					} catch (Exception e) {
						e.printStackTrace();
					}
			    }
			}).start();
			
			p.waitFor();
		} catch (Exception e) {
			result.setMessage(e.getMessage());
			return result;
		}
		result.setSuccess(true);
		return result;
	}
	
	/**
	 * 
	 * <font size="3" color="red"></font><br>
	 * <ol>
	 * <li><a href="http://keren.iteye.com/blog/1773518">所有编码器</a></li>
	 * <li><a href="http://blog.csdn.net/rootusers/article/details/41646557">ffmpeg-比特率，帧率和文件大小</a></li>
	 * <li><a href="http://blog.csdn.net/weiyuefei/article/details/55097266">FFMPEG使用参数详解</a></li>
	 * <li><a href="https://www.ffmpeg.org/download.html">FFMPEG下载地址</a></li>
	 * </ol>
	 * @param codec
	 * @return <font size="2" color="blue"></font>
	 */
	public static ResultBase cover(VideoCoverOrder codec){
		ResultBase result = new ResultBase();
		try {
			codec.check();
//			String codecCommond = "cmd /c ffmpeg -i "+codec.getVideoInputPath()+" -acodec "+codec.getAudioCodec()+
//					" -vcodec "+codec.getVideoCodec()+" -b "+codec.getVideoBitrate()+" -ab "+codec.getAudioBitrate()+" -bufsize "+codec.getBufsize()+" -r "+codec.getFps()+" -s "+codec.getSize()+
//					" -aspect "+codec.getAspect()+" -q 1 -y "+codec.getVideoOutputPath();
			
			LinkedList<String> ffmepgCommand = new LinkedList<String>();
			ffmepgCommand.addFirst("cmd");
			ffmepgCommand.add("/c");
			ffmepgCommand.add("ffmpeg");
			
			ffmepgCommand.add("-i");
			ffmepgCommand.add(codec.getVideoInputPath());
			
			ffmepgCommand.add("-acodec");
			ffmepgCommand.add(codec.getAudioCodec());
			
			ffmepgCommand.add("-vcodec");
			ffmepgCommand.add(codec.getVideoCodec());
			
			ffmepgCommand.add("-b:v");
			ffmepgCommand.add(codec.getVideoBitrate());
			
			ffmepgCommand.add("-b:a");
			ffmepgCommand.add(codec.getAudioBitrate());
			
			if(codec.getPreset() != null){
				ffmepgCommand.add("-preset");
				ffmepgCommand.add(codec.getPreset().getCode());
			}
			if(codec.getProfile() != null){
				ffmepgCommand.add("-profile:v");
				ffmepgCommand.add(codec.getProfile().getCode());
			}
			if(codec.getLevel() != null){
				ffmepgCommand.add("-level");
				ffmepgCommand.add(codec.getLevel().getCode());
			}
			
			ffmepgCommand.add("-psy");
			ffmepgCommand.add("true");
			
			ffmepgCommand.add("-refs");
			ffmepgCommand.add("5");
			
			if(codec.getFps() > 0){
				ffmepgCommand.add("-r");
				ffmepgCommand.add(String.valueOf(codec.getFps()));
			} else if(true){
				ffmepgCommand.add("-maxrate");
				ffmepgCommand.add(String.valueOf(codec.getMaxrate()));
			}
			if(StringUtils.isNotBlank(codec.getSize())){
				ffmepgCommand.add("-s");
				ffmepgCommand.add(codec.getSize());
			}
			
			ffmepgCommand.add("-aspect");
			ffmepgCommand.add(codec.getAspect());
			
//			ffmepgCommand.add("-threads");
//			ffmepgCommand.add("5");
			
//			ffmepgCommand.add("-crf");
//			ffmepgCommand.add("30");
			ffmepgCommand.add("-y");
			ffmepgCommand.addLast(codec.getVideoOutputPath());
			String commandLog = "";
			for(String tmp:ffmepgCommand){
				commandLog += tmp+" ";
			}
			System.out.println(commandLog);
			Process p = Runtime.getRuntime().exec(ffmepgCommand.toArray(new String[0]), null, new File(codec.getFfmpeglib()));
			new Thread(new Runnable() {
			    @Override
				public void run() {
			    	try {
				    	BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(),"utf-8"));
				    	String tmp;
			    		while((tmp = br.readLine())!=null){
			    			System.out.println(tmp);
			    		}
					} catch (Exception e) {
						e.printStackTrace();
					}
			    }
			}).start();
			
			new Thread(new Runnable() {
			    @Override
				public void run() {
			    	try {
				    	BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream(),"utf-8"));
				    	String tmp;
			    		while((tmp = br.readLine())!=null){
			    			System.err.println(tmp);
			    		}
					} catch (Exception e) {
						e.printStackTrace();
					}
			    }
			}).start();
			
			p.waitFor();
		} catch (Exception e) {
			result.setMessage(e.getMessage());
			return result;
		}
		result.setSuccess(true);
		result.setMessage(codec.getVideoInputPath()+"转换成功");
		return result;
	}
}
